package com.example.livereplay.common.service.imp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.livereplay.common.model.enity.SysAttachment;
import com.example.livereplay.common.model.enity.SysUser;
import com.example.livereplay.common.model.enums.UserTypeEnum;
import com.example.livereplay.common.model.request.LoginByPhoneRequest;
import com.example.livereplay.common.model.request.LoginByUserNameRequest;
import com.example.livereplay.common.model.request.UpdatePasswordRequest;
import com.example.livereplay.common.model.request.UserRegisterRequest;
import com.example.livereplay.common.service.FileUploadService;
import com.example.livereplay.common.service.SysUserService;
import com.example.livereplay.exception.BusinessException;
import com.example.livereplay.common.mapper.SysUserMapper;
import com.example.livereplay.common.service.SysAttachmentService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private FileUploadService fileUploadService;
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysAttachmentService sysAttachmentService;


    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    public static final String HEAD = "HEAD";

    // 修改密码
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean userUpdatePassword(UpdatePasswordRequest updatePasswordRequest) {
        final SysUser oldUser = getById(updatePasswordRequest.getUserId());
        // 使用密码编码器验证旧密码是否正确
        if (!passwordEncoder.matches(updatePasswordRequest.getOldPassword(),oldUser.getPassword())) {
            throw new BusinessException("旧密码错误");
        }
        // 对新密码进行加密后设置给用户对象
        oldUser.setPassword(passwordEncoder.encode(updatePasswordRequest.getNewPassword()));
        return updateById(oldUser);
    }

    // 注册
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean userRegister(UserRegisterRequest userRegisterRequest) {
        final long usernameNum = count(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userRegisterRequest.getUsername()));
        final long phone = count(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, userRegisterRequest.getPhone()));
        if (usernameNum > 0) {
            throw new BusinessException("用户名已存在");
        }
        if (phone > 0) {
            throw new BusinessException("手机号已注册过");
        }
        final SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(userRegisterRequest, sysUser);
        // 对用户输入的密码进行加密后再存储
        sysUser.setPassword(passwordEncoder.encode(userRegisterRequest.getPassword()));
        sysUser.setUserType(UserTypeEnum.User.getCode());
        if (save(sysUser)) {
            if (StrUtil.isNotBlank(userRegisterRequest.getHeaderUrl())) {
                sysAttachmentService.saveAttachment(HEAD, sysUser.getId(), userRegisterRequest.getHeaderUrl());
            }
            return true;
        }
        return false;
    }

    // 用户名登录
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean loginByUserName(LoginByUserNameRequest loginByUserNameRequest) {
        final SysUser user = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, loginByUserNameRequest.getUsername())
        );
        if (user == null) {
            throw new BusinessException("用户名错误");
        }
        // 使用密码编码器验证密码是否正确
        if (!passwordEncoder.matches(loginByUserNameRequest.getPassword(),user.getPassword())) {
            throw new BusinessException("密码错误");
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean loginByPhone(LoginByPhoneRequest loginByPhoneRequest) {
        final SysUser user = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getPhone, loginByPhoneRequest.getPhone())
        );
        if (user == null) {
            throw new BusinessException("手机号错误");
        }
        // 使用密码编码器验证密码是否正确
        if (!passwordEncoder.matches(loginByPhoneRequest.getPassword(),user.getPassword())) {
            throw new BusinessException("密码错误");
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysAttachment uploadHead(MultipartFile file) {
        return fileUploadService.uploadSingleFile("/user/head/", null, file);
    }
}
